package vn.conghuy.talkwithme.responsor.responsor;

import java.util.ArrayList;

import vn.conghuy.talkwithme.MyApp;
import vn.conghuy.talkwithme.R;
import vn.conghuy.talkwithme.data.android.ContactModel;
import vn.conghuy.talkwithme.data.sqlmodel.SqlData;
import vn.conghuy.talkwithme.responsor.action.CallAction;
import vn.conghuy.talkwithme.responsor.action.SmsAction;
import vn.conghuy.talkwithme.utils.ArrayListContactWrapper;
import vn.conghuy.talkwithme.utils.IntWrapper;
import vn.conghuy.talkwithme.utils.Parser;
import vn.conghuy.talkwithme.utils.StringWrapper;
import vn.conghuy.talkwithme.utils.Utils;
import android.content.Context;

public class SmsResponsor extends Responsor {
	
	String address = null;
	String content = null;
	public ArrayList<ContactModel> listContact;
	ArrayList<ContactModel> lCallContact;
	MyApp myApp;
	
	private static final int RELATIVE_MISS_INFO= 1;
	private static final int RELATIVE_ASK_CHOOSE_CONTACT = 2;
	
	private static final String TO_KEYWORD = "to";
	
	public SmsResponsor(Context context) {
		super(context);
		this.context = context;
		myApp = (MyApp)context.getApplicationContext();
		listContact = myApp.listContact;
	}
	
	@Override
	public String response(String request) {
		request = request.toLowerCase();
		
		if(Utils.isExistStringInArray(SqlData.stopWords, request)){
			relativeLastResponse = RELATIVE_NONE;
			return Utils.getRandomString(SqlData.taskStop);
		}
		switch (relativeLastResponse) {
		
		case RELATIVE_NONE:
			
			String namePhrase = null;
			int parseResult = Parser.PARSE_ADDRESS_FAIL;
			
			StringWrapper smsVerbWrapper = new StringWrapper();
			StringWrapper smsKeywordWrapper = new StringWrapper();
			
			if(Utils.isExistElemInArrayIsWordOfStr(SqlData.smsVerbs, request, smsVerbWrapper)){
				int verbIndex = request.indexOf(smsVerbWrapper.getStr());
				request = request.substring(verbIndex);
				if(Utils.isExistElemInArrayIsWordOfStr(SqlData.smsKeywords, request, smsKeywordWrapper)){
				
				
					//get index of some keyword
					int toIndex = toIndex(request);
					
					StringWrapper contentKeywordWrapper = new StringWrapper();
					int contentIndex = contentIndex(request, contentKeywordWrapper);
					String contentKeyword = contentKeywordWrapper.getStr();
					
					// analyse name phrase and content phrase use above keyword
					if(toIndex != -1){						//if request has "to" keyword
						if(contentIndex > toIndex){			// and "content" keyword after "to"
							namePhrase = request.substring(toIndex + 3, contentIndex - 1);		// 3 is "to".lenght +1
							parseResult = parseAddressFromNamePhrase(namePhrase);
						}
						else{
							namePhrase = request.substring(toIndex + 3);
							parseResult = parseAddressFromNamePhrase(namePhrase);
						}
					}
					
					if(contentIndex != -1){
						if(toIndex > contentIndex){
							content = request.substring(contentIndex + contentKeyword.length() + 1, toIndex - 1);
						}
						else{
							content = request.substring(contentIndex + contentKeyword.length() + 1);
						}
					}
					
					if(address == null && parseResult == Parser.PARSE_ADDRESS_MULTI){
						relativeLastResponse = RELATIVE_ASK_CHOOSE_CONTACT;
						return responseStringToSelectMultiContact();
					}
					
					return checkMissingInfoAndSendSms();
				}
			}
			break;
			
		case RELATIVE_MISS_INFO:
			
			namePhrase = null;
			parseResult = Parser.PARSE_ADDRESS_FAIL;
			if(address == null && content == null){
				
				//get index of some keyword
				int toIndex = toIndex(request);
				
				StringWrapper contentKeywordWrapper = new StringWrapper();
				int contentIndex = contentIndex(request, contentKeywordWrapper);
				String contentKeyword = contentKeywordWrapper.getStr();
				
				//TODO do like EmailResponsor
				// analyse name phrase and content phrase use above keyword
				if(toIndex != -1){						//if request has "to" keyword
					if(contentIndex > toIndex){			// and "content" keyword after "to"
						namePhrase = request.substring(toIndex + 3, contentIndex - 1);		// 3 is "to".lenght +1
					}
					else{
						namePhrase = request.substring(toIndex + 3);
						if(content == null && toIndex > 0){
							content = request.substring(0, toIndex - 1);	
							if(content.length() < 1) content = null;
						}
					}
					parseResult = parseAddressFromNamePhrase(namePhrase);
				}
				
				if(contentIndex != -1){
					if(toIndex > contentIndex){
						content = request.substring(contentIndex + contentKeyword.length() + 1, toIndex - 1);
					}
					else{
						content = request.substring(contentIndex + contentKeyword.length() + 1);
						if(namePhrase == null && contentIndex > 0){
							namePhrase = request.substring(0, contentIndex - 1);
							parseResult = parseAddressFromNamePhrase(namePhrase);
						}
					}
				}
				else if(toIndex == -1){			// have no "to" and "content" keyword
					parseResult = parseAddressFromNamePhrase(request);
					if(parseResult == Parser.PARSE_ADDRESS_FAIL)
						content = request;
				}
			}
			else if(address == null){
				namePhrase = request;
				parseResult = parseAddressFromNamePhrase(namePhrase);
			}
			else if(content == null){
				content = request;
			}
			
			if(address == null && parseResult == Parser.PARSE_ADDRESS_MULTI){
				relativeLastResponse = RELATIVE_ASK_CHOOSE_CONTACT;
				return responseStringToSelectMultiContact();
			}
			
			return checkMissingInfoAndSendSms();
			
		case RELATIVE_ASK_CHOOSE_CONTACT:
			ContactModel contact = ContactModel.isExistElemInArrayHasNameBeSubStringOfStr(lCallContact, request);
			if(contact != null){
				address = contact.getAddress();
				return checkMissingInfoAndSendSms();
			}
			else{
				IntWrapper numberWrapper = new IntWrapper();
				if(Utils.hasNumber(request, numberWrapper)){
					int number = numberWrapper.getInt();
					if(number <= lCallContact.size() + 1){
						contact = lCallContact.get(number - 1);
						address = contact.getAddress();
						return checkMissingInfoAndSendSms();
					}
				}
				
				relativeLastResponse = RELATIVE_ASK_CHOOSE_CONTACT;
				return responseStringToSelectMultiContact();
			}

		default:
			break;
		}
		return super.response(request);
	}
	
	@Override
	public int relativeWithLastRequest(String sentence) {
		return relativeLastResponse;
	}
	
	private int parseAddressFromNamePhrase(String namePhrase){
		StringWrapper addressWrapper = new StringWrapper();
		ArrayListContactWrapper lCallContactWrapper = new ArrayListContactWrapper();
		int result = Parser.parseAddressFromNamePhrase(namePhrase, listContact, lCallContactWrapper, addressWrapper);
		address = addressWrapper.getStr();
		lCallContact = lCallContactWrapper.getArrayList();
		return result;
	}
	
	boolean sendSms(){
		
		if(content == null || address == null) return false;
		
		SmsAction smsAction = new SmsAction(context, address, content);
		smsAction.doAction();
		return true;
	}
	
	public void reset(){
		super.reset();
		address = null;
		content = null;
	}
	
	int toIndex(String request){
		return Utils.indexOfWord(request, TO_KEYWORD);
	}
	
	int contentIndex(String request, StringWrapper outContentKeyword){
		int contentIndex;
		for(String contentWord:SqlData.smsContentWords){
			contentIndex = Utils.lastIndexOfWord(request, contentWord);
			if(contentIndex != -1){
				outContentKeyword.setStr(contentWord);
				return contentIndex;
			}
		}
		return -1;
	}
	
	private String responseStringToSelectMultiContact(){
		String responseString = Utils.getRandomString(SqlData.commonAskChooseContact) + " ";
		int i = 0;
		for(ContactModel contactModel:lCallContact){
			responseString += "\n" + (i+1) + " - " + contactModel.getName() + ", ";
			i++;
		}
		responseString = responseString.substring(0, responseString.length() - 2);
		return responseString;
	}
	
	private String checkMissingInfoAndSendSms() {
		if(address == null && content == null){
			relativeLastResponse = RELATIVE_MISS_INFO;
			return Utils.getRandomString(SqlData.smsMissAddressAndContent);
		}
		else if(address == null){
			relativeLastResponse = RELATIVE_MISS_INFO;
			return Utils.getRandomString(SqlData.smsMissAddress);
		}
		else if(content == null){
			relativeLastResponse = RELATIVE_MISS_INFO;
			return Utils.getRandomString(SqlData.smsMissContent);
		}
		
		boolean result = sendSms();
		if(result == true){
			relativeLastResponse = RELATIVE_NONE;
			return context.getString(R.string.sms_command);
		}
		return null;
	}
	
	@Override
	public int indexOfMainVerb(String request) {
		StringWrapper smsVerbWrapper = new StringWrapper();
		
		if(Utils.isExistElemInArrayIsWordOfStr(SqlData.smsVerbs, request, smsVerbWrapper))
			return Utils.indexOfWord(request, smsVerbWrapper.getStr());
		else return super.indexOfMainVerb(request);
	}
	
	public void resetAfterResume(){
		listContact = myApp.listContact;
	}
}
